package levelrewind.android.app;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import levelrewind.android.app.adapter.GameListAdapter;
import levelrewind.android.app.model.LineChart;
import levelrewind.android.app.model.PictureHandler;
import levelrewind.android.app.model.RestDataHandler;
import levelrewind.android.app.model.Util;
import levelrewind.android.app.model.Util.Emotion;
import levelrewind.android.app.vo.Battle;
import levelrewind.android.app.vo.BattlePerson;
import levelrewind.android.app.vo.BattleScore;
import levelrewind.android.app.vo.Game;
import levelrewind.android.app.vo.Person;

import org.achartengine.GraphicalView;

import com.greystripe.sdk.GSMobileBannerAdView;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class DisplayBattleActivity extends Activity implements OnItemClickListener {
	private ImageView person1_pic;
	private ImageView person2_pic;
	private TextView person1_name;
	private TextView person2_name;
	private TextView time_left;
	private LinearLayout person1_chart;
	private LinearLayout person2_chart;
	private TextView person1_score;
	private TextView person2_score;
	private Button person1_playbtn;
	private Button person2_playbtn;
	private Button back;
	
	private ListView mListview;
	private AlertDialog mAlertDialog;
	private GSMobileBannerAdView adBanner;
	
	private Battle battle;
	private BattlePerson[] battlePerson;
	private Person person1;
	private Person person2;
	private Person personOnPlay;
	private long score;
	
	private final int NEW_GAME = 0;
		
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.battle);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        initializeViews();

        getBattle();
        display();
        
        // Set game list dialog
        RestDataHandler dh = new RestDataHandler(this.getApplicationContext());
        Game[] result = dh.getGamesFromDevice();
        mListview = new ListView(this);
        GameListAdapter adapter = new GameListAdapter(DisplayBattleActivity.this);
		for(int i=0; i<result.length;i++) {
			adapter.addItem(result[i]);
		}

        mListview.setOnItemClickListener(this);
        mListview.setAdapter(adapter);
        prepareAlertDialog();
        
        //Add banner
    	adBanner = (GSMobileBannerAdView)this.findViewById(R.id.gsBanner);
    	adBanner.refresh();
    	
    	//Add banner under layout
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		params.addRule(RelativeLayout.ABOVE, R.id.gsBanner);
    	LinearLayout main = (LinearLayout)findViewById(R.id.mainLayout);
    	main.setLayoutParams(params);
    }
	
	private void initializeViews()
	{
		person1_name = (TextView)findViewById(R.id.battle_person1_name);
		person2_name = (TextView)findViewById(R.id.battle_person2_name);
		person1_pic = (ImageView)findViewById(R.id.battle_person1_pic);
		person2_pic = (ImageView)findViewById(R.id.battle_person2_pic);
		person1_chart = (LinearLayout)findViewById(R.id.battle_person1_chart);
		person2_chart = (LinearLayout)findViewById(R.id.battle_person2_chart);
		person1_score = (TextView)findViewById(R.id.battle_person1_score);
		person2_score = (TextView)findViewById(R.id.battle_person2_score);
		person1_playbtn = (Button)findViewById(R.id.battle_person1_play);
		person2_playbtn = (Button)findViewById(R.id.battle_person2_play);
		back = (Button)findViewById(R.id.battle_back);
		
		person1_name.setTypeface(Util.customFont(this));
		person2_name.setTypeface(Util.customFont(this));
		person1_score.setTypeface(Util.customFont(this));
		person2_score.setTypeface(Util.customFont(this));
		person1_playbtn.setTypeface(Util.customFont(this));
		person2_playbtn.setTypeface(Util.customFont(this));
		back.setTypeface(Util.customFont(this));
		
		back.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
		time_left = (TextView)findViewById(R.id.battle_cd);
	}
	
	private void getBattle()
	{
		Bundle b = new Bundle();
		b = getIntent().getExtras();
		if (b != null) battle = (Battle) Util.getBundleObject(b);
		battlePerson = battle.getPersons();
		person1 = battlePerson[0].getPerson();
		person2 = battlePerson[1].getPerson();
	}
	
	private void display() {
		person1_name.setText(person1.getName());
		person2_name.setText(person2.getName());
		
		person1_score.setText(Util.formatNumber(battlePerson[0].getScore()));
		person2_score.setText(Util.formatNumber(battlePerson[1].getScore()));
		
		PictureHandler.viewImageFromDevice(this, person1, Emotion.NORMAL, person1_pic);
		PictureHandler.viewImageFromDevice(this, person2, Emotion.NORMAL, person2_pic);
		
		//Get server time and calculate it to time left
		//new GetServerTimeTask().execute();
		setTimeLeft();
		
		new GetBattleScoreTask().execute(battle.getId());
		
	}
	
	@TargetApi(9)
	private void setTimeLeft() {
		// Set the end date to stop at the last time of the day by add 1 more day
    	// current format of EndDate = yyyy-MM-dd 00:00:00
		Date endDate = battle.getEndDate();
    	Calendar c = Calendar.getInstance();
    	c.setTime(endDate);
    	c.add(Calendar.DAY_OF_YEAR, 1);
    	endDate = c.getTime();
    	
		//Calculate days left until the end date
    	Date now = new Date();
		long difference = endDate.getTime() - now.getTime(); 
		long millis = TimeUnit.MILLISECONDS.toMillis(difference);
		
		//Calculate time left until midnight	
		new CountDownTimer(millis, 1000){ 
	      public void onTick(long millisUntilFinished) {   
	    	  long hour = (millisUntilFinished/(60*60*1000))%24;
	    	  long minute = (millisUntilFinished/(60*1000))%60;
	    	  long seconde = (millisUntilFinished/1000)%60;
	       String timeLeft = getString(R.string.battle_cd, TimeUnit.MILLISECONDS.toDays(millisUntilFinished)
	    		   , String.format("%02d", hour)+":"+String.format("%02d", minute)+":"+String.format("%02d", seconde)) ;
	       time_left.setText(timeLeft);
	      } 
	
	      public void onFinish() { 
	    	time_left.setText("TIME OUT!");
	      } 
	   }.start(); 	
	}
	
	BattleScore battleScore1;
	BattleScore battleScore2;
	private void matchPersons(BattleScore[] bs) {
		if (bs == null || bs.length == 0) return;
		
		// battle for person1
		if (bs[0].getPersonId() == battlePerson[0].getPerson().getId() ){
			battleScore1 = bs[0];
		}
		else if (bs[0].getPersonId() == battlePerson[1].getPerson().getId() ){
			battleScore2 = bs[0];
		}
		
		// battle for person2
		if (bs.length == 2) {
			if (bs[1].getPersonId() == battlePerson[0].getPerson().getId() ){
				battleScore1 = bs[1];
			}
			else if (bs[1].getPersonId() == battlePerson[1].getPerson().getId() ){
				battleScore2 = bs[1];
			}
		}
	}
	
	private void displayPersonPictureAndChart(BattleScore[] result) {
		
		matchPersons(result);
		
		long person1TotalScore = battlePerson[0].getScore();
		long person2TotalScore = battlePerson[1].getScore();
		
		// Set score, chart for person1
		if (battleScore1 != null) {
			//Update total score
			person1TotalScore = Util.sum(battleScore1.getScore());
			person1_score.setText(Util.formatNumber(person1TotalScore));
			
			// Create charts
			createChart(battleScore1.getDate(), battleScore1.getScore(), person1_chart);
		}
		
		// Set score, chart for person2
		if (battleScore2 != null) {
			person2TotalScore = Util.sum(battleScore2.getScore());
			person2_score.setText(Util.formatNumber(person2TotalScore));
			createChart(battleScore2.getDate(), battleScore2.getScore(), person2_chart);
		}
		
		// Display pictures
		if (person1TotalScore > person2TotalScore) {
			PictureHandler.downloadImageAndDisplay(this, person1, Emotion.HAPPY, person1_pic);
			PictureHandler.downloadImageAndDisplay(this, person2, Emotion.SAD, person2_pic);
		}
		else if (person1TotalScore < person2TotalScore) {
			PictureHandler.downloadImageAndDisplay(this, person1, Emotion.SAD, person1_pic);
			PictureHandler.downloadImageAndDisplay(this, person2, Emotion.HAPPY, person2_pic);
		}
		else {
			PictureHandler.viewImageFromDevice(this, person1, Emotion.NORMAL, person1_pic);
			PictureHandler.viewImageFromDevice(this, person2, Emotion.NORMAL, person2_pic);
		}
	}

	private void createChart(ArrayList<Date> dList, ArrayList<Long> scores, LinearLayout layout){
		LineChart lc = new LineChart(this);
		layout.removeAllViews();
		
		GraphicalView mChartView = lc.createChart(dList, scores);
    	Display display = getWindowManager().getDefaultDisplay(); 
    	int w = display.getWidth();
    	
    	layout.addView(mChartView, new LinearLayout.LayoutParams(w/5 * 3, 200)); 
    }
	
	public void prepareAlertDialog() {
	  	WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
	  	AlertDialog.Builder mBuider = new AlertDialog.Builder(DisplayBattleActivity.this);
	  	mBuider.setTitle(getString(R.string.available_game));
	  	mBuider.setNegativeButton(getString(R.string.cancel),
	  	new DialogInterface.OnClickListener() {
	  	     @Override
	  	     public void onClick(DialogInterface dialog, int which) {
	  	      dialog.cancel();
	  	     }
	  	    });
	  	mBuider.setView(mListview);
	  	mBuider.setInverseBackgroundForced(true);
	  	mAlertDialog = mBuider.create();
	  	  
	  	lp.copyFrom(mAlertDialog.getWindow().getAttributes());
	}
	
	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long log)
	{
    	
    }
	
	// Play button for person1 clicked
	public void openGame1Clicked(View view)
    {
		personOnPlay = person1;
		mAlertDialog.show();
    }
	
	// Play button for person2 clicked
	public void openGame2Clicked(View view)
    {
		personOnPlay = person2;
		mAlertDialog.show();
    }
	
	// Called from GameListAdapter
	public void startGame(int gameID) {
		mAlertDialog.dismiss();
		Intent intent = new Intent();
    	intent.setClassName("com.levelrewind.zombiefans", "com.levelrewind.zombiefans.ZombieActivity");
    	startActivityForResult(intent, NEW_GAME);
    }
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    	super.onActivityResult(requestCode, resultCode, data);
    	
    	if (requestCode == NEW_GAME) { 
    	 
    	     if(resultCode == RESULT_OK){ 
    	    	Bundle extras = data.getExtras();
     			score = Long.parseLong(extras.get("score").toString());
     			Log.i("Battle game score af "+personOnPlay.getName(), score+"");
    	    	 //updateBattleScore for personOnPlay
     			new UpdateBattleScoreTask().execute();
     			
    	     }
    	     else if (resultCode == RESULT_CANCELED) { } 
    	 
    	}  
    }
	
	private class GetBattleScoreTask extends AsyncTask<Integer, Void, BattleScore[]>
    {    	
		protected void onPostExecute(BattleScore[] result) {
			if (result == null) return;
			displayPersonPictureAndChart(result);
    	}
    	
		@Override
		protected BattleScore[] doInBackground(Integer...params ) {

			return RestDataHandler.getBattleScores(params[0]);
		}
    	
    }
    
    private class UpdateBattleScoreTask extends AsyncTask<Void, Void, Boolean>
    {    	
		protected void onPostExecute(Boolean result) {
			new GetBattleScoreTask().execute(battle.getId());
    	}
    	
		@Override
		protected Boolean doInBackground(Void...params ) {
			return RestDataHandler.updateBattleScore(battle.getId(), personOnPlay.getId(), score);
		}
    	
    }
	
}
